Skip to content

fix(cors): allow X-Cryptify-Source in browser preflights#189

Merged
rubenhensen merged 1 commit into
mainfrom
fix/cors-allow-x-cryptify-source
Jul 14, 2026
Merged

fix(cors): allow X-Cryptify-Source in browser preflights#189
rubenhensen merged 1 commit into
mainfrom
fix/cors-allow-x-cryptify-source

Conversation

@rubenhensen

Copy link
Copy Markdown
Contributor

Problem

Uploads from the staging website fail with CORS Missing Allow Origin on the OPTIONS /fileupload/init preflight.

Since encryption4all/postguard-website#228 the website sends X-Cryptify-Source: website on every pg-js request so cryptify can attribute traffic per channel. Cryptify consumes that header in metrics.rs, but it was never added to the CORS allowed_headers list. Browsers include it in the preflight's Access-Control-Request-Headers, rocket_cors rejects the preflight with a 403 that carries no Access-Control-Allow-Origin, and the browser blocks the upload before it starts.

Verified against the live servers: the preflight with x-cryptify-source gets 403 without CORS headers on staging, and a clean 204 without the header. Production is unaffected only because its nginx answers preflights itself (and mirrors requested headers) — the rocket_cors config isn't exercised there.

Fix

  • Add X-Cryptify-Source to the CORS allowed_headers list.
  • Extract build_cors() and use it from both the production launch path and the test harness. The existing preflight smoke test asserted against a test-local copy of the CORS config, which is exactly why this regression went undetected.
  • Add a regression test that preflights POST /fileupload/init with X-Cryptify-Source and asserts it is advertised in Access-Control-Allow-Headers.

Staging runs the edge image tag, so it picks this up on the next image build + pod restart. No ops changes needed — the header allow-list is not part of the ops-templated config.

@rubenhensen

Copy link
Copy Markdown
Contributor Author

/dobby fix conflicts

@dobby-coder dobby-coder Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved — clean, well-scoped CORS fix.

Reviewed against the Review-Dobby findings (none) and a per-rule compliance sweep (Haiku sub-agents over the applicable rules). No findings from either pass.

Highlights:

  • Root cause correctly identified: X-Cryptify-Source (postguard-website#228) rode into the preflight's Access-Control-Request-Headers but was missing from rocket_cors' allowed_headers, so the preflight 403'd without an Access-Control-Allow-Origin.
  • build_cors() extracted and shared by the production launch path and the test harness — this collapses the duplicated test-local CORS config that let the regression slip through, which is the real fix here.
  • Regression test preflights POST /fileupload/init with X-Cryptify-Source and asserts it's advertised in Access-Control-Allow-Headers — matches the cryptify test-harness conventions (#[rocket::async_test], per-test uuid temp data_dir, cleanup).
  • Conventional-commit title, tests-on-fixes, and fmt/clippy all satisfied (CI: 120 passed, clippy + fmt clean).

No ops changes needed since the allow-list isn't ops-templated; staging picks it up on the next edge image build. 👍

The website tags its uploads with X-Cryptify-Source for per-channel
metrics (postguard-website#228), but the header was never added to the
CORS allow-list. Browsers include it in the preflight's
Access-Control-Request-Headers, rocket_cors rejects the preflight with
a 403 carrying no Access-Control-Allow-Origin, and uploads from the
website fail before they start. Staging hits this directly; production
only works because its nginx answers preflights itself.

Add the header to the allow-list, and extract build_cors() so the
preflight smoke tests exercise the production CORS config instead of a
test-local copy — the duplicated config is why the existing smoke test
couldn't catch this regression.
@rubenhensen
rubenhensen force-pushed the fix/cors-allow-x-cryptify-source branch from 41dda25 to 0d6be9a Compare July 14, 2026 11:55
@rubenhensen
rubenhensen merged commit 82fa1e9 into main Jul 14, 2026
6 checks passed
@rubenhensen
rubenhensen deleted the fix/cors-allow-x-cryptify-source branch July 14, 2026 11:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant